Обмен данными с PRU
Для обмена данными с PRU используется программы BlinkningLeds_Pru0MemoryRead
и BlinkningLeds_Pru0MemoryWrite
. Их текст генерируется в зависимости от того, какие переменные отмечены на обмен между PRU и основным циклом.
Обмен данными занимает ресурсы (регистры, память) PRU, поэтому чтобы увеличить набор синхронизируемых переменных нужно пересобирать (перекомпилировать) PRU программу и после этого переимпортировать результирующий .exp
.
Следует понимать, что:
- При обмене происходит обновление всех переменных (либо читаются все, либо пишутся все). Нет смысла вызывать обмен несколько раз только для того, чтобы по-очереди передать каждую отдельную переменную.
- Во время обмена данными PRU ядро не выполняет пользовательскую программу и не опрашивает входы. Получаемые значения целостны и согласованы между собой.
- Для отладки PRU в режиме online, можно отмечать некоторые переменные на обмен, и тогда их значения будет видно в CoDeSys online
- Сначала происходит передача данных в PRU, а затем чтение данных из PRU. Между этими двумя операциями PRU может успеть выполнить свой цикл.
- Не стоит делать
input output
переменные для обмена. Они будут работать какinput
.
Есть несколько направлений, где могут передаваться данные:
- Основная программа → PRU
- PRU → основная программа
- PRU0 ↔ PRU1
Общий подход
При составлении основной программы PLC_PRG
стоит придерживаться следующего подхода:
PROGRAM PLC_PRG
...
(* В начале программы читаем состояние PRU *)
BlinkningLeds_Pru0MemoryRead()
(* К значениям из PRU можно обращаться через точку *)
BlinkningLeds_Pru0MemoryWrite.
(* В конце программы записываем новые значения в PRU *)
BlinkningLeds_Pru0MemoryWrite()
END_PROGRAM
Передача данных в PRU
Если PRU управляет шаговым двигателем, то передача данных в PRU позволит настроить PRU программу на нужное количество импульсов, скорость подачи импульсов.
Если же необходимо задействовать “быстрый” выход как обычный (т.е. управлять им из основной программы), то это тоже делается через передачу данных из основного цикла в PRU программу. PRU программа управляет выходом, а команда на включение-выключение передаётся между основным циклом и PRU программой.
Рассмотрим PRU программу
PROGRAM OUT_CONTROL
variables:
<no variables>
body:
FAST_OUTPUTS(out3 := FALSE);
END_PROGRAM
Добавим в неё возможность управления быстрым выходом по сигналу “основного цикла”. Для этого нужно объявить переменную.
Если сейчас запутить программу, то ничего не изменится. Выход по-прежнему будет неактивен, а всё потому, что переменная active
не обозначена к обмену между основным циклом и PRU программой.
Для того, чтобы управлять этой переменной из основного цикла – нужно установить курсор на строку с объявлением переменной и нажать alt+enter
(или на возникшую лампочку слева).
И в появившемся меню выбрать пункт “Exchange this variable with HOST”
Код станет выглядеть вот так:
При компиляции этой PRU программы, в результирующей программе OutControlPruConfig_Pru0MemoryWrite
будет переменная с именем OUT_CONTROL_active
(название складывается из названия блока в котором находится переменная и названия самой переменной).
PROGRAM OutControlPruConfig_Pru0MemoryWrite
VAR_INPUT
OUT_CONTROL_active : BOOL;
END_VAR
VAR_OUTPUT
running : BOOL;
writeFails : DWORD;
readFails : DWORD;
END_VAR
Таким образом, чтобы передать данные из основного цикла в PRU нужно выполнить такой фрагмент кода:
OutControlPruConfig_Pru0MemoryWrite(
OUT_CONTROL_active := ...
);
Сам обмен происходит в момент вызова MemoryWrite
.
Чтение данных из PRU
В целом, чтение ничем не отличается от записи, за исключением того, что используется программа MemoryRead
вместо MemoryWrite
. Точно так же нужно объявить переменную (на этот раз output
, а не input
), и настроить для неё Exchange with HOST
.
Например, если в основном цикле нужно значение “быстрого входа”, то это можно реализовать следующим образом:
Обмен в случае функциональных блоков
Функциональные блоки зачастую содержат много вспомогательных входов-выходов, и не все они необходимы для конкретного применения.
Например:
- Блок чтения быстрых входов
FAST_INPUTS
возвращает 4 значения, а кому-то может требоваться только одно-два - Блок энкодера может возвращать как само положение, так и счётчик обработанных импульсов
Если включать в обмен все-все переменные, то ресурсы закончатся.
Поэтому, когда в обмен включается переменная-блок, то появляется возможность сузить набор переменных.
Например, рассмотрим программу, обработки значения с энкодера
Здесь в параметрах @Export
перечислены те переменные блока энкодера, которые нужно синхронизировать с основным циклом.
После компиляции и импорта .exp
файла, на стороне КДС возникнет три VAR_OUTPUT
переменных:
PROCESS_ENCODER_encoder_counter : WORD;
PROCESS_ENCODER_encoder_position : WORD;
PROCESS_ENCODER_encoder_zeroDetected : BOOL;
Комментировать